#include "m_nrf2401.h"
#include "m_log.h"
#include "m_utils.h"
#include "m_spi.h"
#include "m_gpio.h"
#include "m_time.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "hi_gpio.h"

#define M_NRF_GPIO_CE   HI_GPIO_IDX_9
#define M_NRF_GPIO_IRQ  HI_GPIO_IDX_10

#define M_NRF_REG_CONFIG_VAL        (unsigned char)0x08   // 默认只使用CRC校验，即：0000 1000
#define M_NRF_REG_EN_AA_VAL         (unsigned char)0x00       // 默认关闭所有通道自动应答(默认值)
#define M_NRF_REG_EN_RXADDR_VAL     (unsigned char)(1 << M_NRF_BIT_EN_RXADDR_P0 | 1 << M_NRF_BIT_EN_RXADDR_P1)   // 默认只启用数据接收通道0，1(默认值)
#define M_NRF_REG_SETUP_AW_VAL      (unsigned char)(3 << M_NRF_BIT_SETUP_AW)     // 接收、发送地址宽度：5个字节（默认值）
#define M_NRF_REG_SETUP_RETR_VAL    (unsigned char)0x00       // 禁止自动重发
#define M_NRF_REG_RF_CH_VAL         (unsigned char)0x7F    // 工作通道频率，范围0x00~0x7F，默认值为：0x02
#define M_NRF_REG_RF_SETUP_VAL      (unsigned char)0x0F    // 数据传输2Mbps，发射功能0dBm，默认值
#define M_NRF_REG_RX_PW_VAL         (unsigned char)10      // 接收数据通道有效数据宽度(字节数)


typedef enum {
    PW_UP_TX_ON,
    PW_UP_TX_OFF,
    PW_UP_RX_ON,
    PW_UP_RX_OFF,
    PW_DW_TX_ON,
    PW_DW_TX_OFF,
    PW_DW_RX_ON,
    PW_DW_RX_OFF
} m_nrf_mode;

static unsigned char m_nrf_reg_tx_addr_val[] = {0xAA, 0xAA, 0xAA, 0xAA, 0x00};  // 发送地址，长度要与M_NRF_REG_SETUP_AW设置一致
static unsigned char m_nrf_reg_rx_addr_val[] = {0xBB, 0xAA, 0xAA, 0xAA, 0x00};  // 接收起始地址，长度要与M_NRF_REG_SETUP_AW设置一致

static int m_nrf_ce_init();
static int m_nrf_irq_init();
static int m_nrf_reg_init();
static int m_nrf_reg_write(unsigned int reg, unsigned char val);
static int m_nrf_reg_write_buf(unsigned int reg, unsigned char *buf, unsigned int size);
static int m_nrf_ce_high();
static int m_nrf_ce_low();
static int m_nrf_reg_value();
static int m_nrf_reg_read(unsigned int reg, unsigned char *val);
static int m_nrf_reg_read_buf(unsigned int reg, unsigned char *buf, unsigned int size);

/** nrf2401模块初始化，只调用一次 */
int m_nrf_init()
{
    m_log_t(M_NRF2401_H, "nrf init...\n");
    //hi_gpio_deinit();
    int r = m_gpio_init();
    if (r != 0) {
        return r;
    }
    //spi_config_gpio(g_spiId);
    r = m_spi_init();
    if (r != 0) {
        return r;
    }
    m_sleep(1000); /* 1000 */
    r = m_nrf_ce_init();
    if (r != 0) {
        return r;
    }
    r = m_nrf_irq_init();
    if (r != 0) {
        return r;
    }
    r = m_nrf_reg_init();
    if (r != 0) {
        return r;
    }
    m_log_t(M_NRF2401_H, "nrf init success\n");
    return 0;
}
/** 进入发送模式 */
int m_nrf_tx_mode()
{
    m_log_t(M_NRF2401_H, "nrf to tx mode...\n");
    m_nrf_reg_write(M_NRF_REG_CONFIG, M_NRF_REG_CONFIG_VAL | (1 << M_NRF_BIT_PWR_UP) & ~(1 << M_NRF_BIT_PRIM_RX));
    m_delay(1500);// 掉电模式到发送模式要经过1.5毫秒待机模式
    m_nrf_ce_high();
    m_delay(130);// 待机模式需要130微秒进入发送模式
    m_log_t(M_NRF2401_H, "nrf to tx mode finish\n");
    return 0;
}
/** 进入接收模式 */
int m_nrf_rx_mode()
{
    m_log_t(M_NRF2401_H, "nrf to rx mode...\n");
    m_nrf_reg_write(M_NRF_REG_CONFIG, M_NRF_REG_CONFIG_VAL | (1 << M_NRF_BIT_PWR_UP) | (1 << M_NRF_BIT_PRIM_RX));
    m_delay(1500);// 掉电模式到接收模式要经过1.5毫秒待机模式
    m_nrf_ce_high();
    m_delay(130);// 待机模式需要130微秒进入接收模式
    m_log_t(M_NRF2401_H, "nrf to rx mode finish\n");
    return 0;
}
/** 进入待机模式I: sleep */
int m_nrf_sl_mode()
{
    m_log_t(M_NRF2401_H, "nrf to sl mode...\n");
    m_nrf_ce_low();
    m_nrf_reg_write(M_NRF_REG_CONFIG, M_NRF_REG_CONFIG_VAL | 1 << M_NRF_BIT_PWR_UP);
    m_log_t(M_NRF2401_H, "nrf to sl mode finish\n");
    return 0;
}
/** 进入掉电模式: power down */
int m_nrf_pd_mode()
{
    m_log_t(M_NRF2401_H, "nrf to pd mode...\n");
    m_nrf_ce_low();
    m_nrf_reg_write(M_NRF_REG_CONFIG, M_NRF_REG_CONFIG_VAL);
    m_log_t(M_NRF2401_H, "nrf to pd mode finish\n");
    return 0;
}

/** 发送数据 */
int m_nrf_host_tx_data(unsigned char *data, int size)
{
    m_log_t(M_NRF2401_H, "nrf host tx data...\n");
    if (size == 0 || data == NULL) {
        m_log_e(M_NRF2401_H, "nrf host tx data fail: no data!\n");
        return -1;
    }

    #ifdef M_LOG_DEBUG
    unsigned char hex[size * 2 + 1];
    m_to_hex(data, size, hex);
    m_log_d(M_NRF2401_H, "host_tx_data-> data=%s\n", hex);
    int step = 0;
    #endif

    int r;
    int index = 0;
    int wSize = 1 + M_NRF_REG_RX_PW_VAL;    // write size
    int i;                                  // step content size
    unsigned char wBuf[wSize];              // write buf
    do {
        memset_s(&wBuf, sizeof(wBuf), 0, sizeof(wBuf));
        wBuf[0] = M_NRF_TX_WRITE;   // fix byte
        for (i = 0; i < M_NRF_REG_RX_PW_VAL && index < size; i++, index++) {
            *(wBuf + 1 + i) = *(data + index);
        }

        #ifdef M_LOG_DEBUG
        unsigned char hex[(i + 1) * 2 + 1];
        m_to_hex(wBuf, i + 1, hex);
        m_log_d(M_NRF2401_H, "host_tx_data-> cmd[%d]=%s\n", step, hex);// i + wBuf[0]
        step++;
        #endif

        m_spi_data data = {
            .sendBuf = wBuf,
            .recvBuf = wBuf,
            .recvSize = wSize
        };
        r = m_spi_host_write_read(&data);
        if (r != 0) {
            m_log_e(M_NRF2401_H, "nrf host tx data fail: size=%d, index=%d, err=0x%02x\n", size, index, r);
            return r;
        }
    } while(index < size);
    m_log_t(M_NRF2401_H, "nrf host tx data finish\n");
    return 0;
}

static int m_nrf_ce_init()
{
    int r = m_gpio_set_dir(M_NRF_GPIO_CE, M_GPIO_OUT);
    if (r != 0) {
        m_log_e(M_NRF2401_H, "nrf ce set dir fail: dir=%d, err=0x%02x\n", HI_GPIO_DIR_OUT, r);
        return r;
    }
    r = m_gpio_set_val(M_NRF_GPIO_CE, M_GPIO_LOW);
    if (r != 0) {
        m_log_e(M_NRF2401_H, "nrf ce set val fail: val=%d, err=0x%02x\n", HI_GPIO_VALUE0, r);
        return r;
    }
    m_log_t(M_NRF2401_H, "nrf ce init success\n");
    return m_nrf_ce_low();
}

static int m_nrf_ce_high()
{
    int r = m_gpio_set_val(M_NRF_GPIO_CE, M_GPIO_HIGH);
    if (r != 0) {
        m_log_e(M_NRF2401_H, "nrf ce set high fail: 0x%02x\n", r);
        return r;
    }
    m_delay(14);// CE高电平至少保持10微秒 + CSN为低电平，CE上升沿的延迟时间4微秒
    return 0;
}

static int m_nrf_ce_low()
{
    int r = m_gpio_set_val(M_NRF_GPIO_CE, M_GPIO_LOW);
    if (r != 0) {
        m_log_e(M_NRF2401_H, "nrf ce set low fail: 0x%02x\n", r);
        return r;
    }
    return 0;
}

static void m_nrf_irq_callback(void *arg)
{
    m_log_i(M_NRF2401_H, "m_nrf_irq_callback come on!!!!\n");
}

static int m_nrf_irq_init()
{
    int r = m_gpio_set_dir(M_NRF_GPIO_IRQ, M_GPIO_IN);
    if (r != 0) {
        m_log_e(M_NRF2401_H, "nrf irq set dir fail: 0x%02x\n", r);
        return r;
    }
    //r = hi_gpio_register_isr_function(M_NRF_GPIO_IRQ, HI_INT_TYPE_LEVEL, HI_GPIO_EDGE_FALL_LEVEL_LOW, m_nrf_irq_callback, NULL);
    if (r != 0) {
        m_log_e(M_NRF2401_H, "nrf irq set callback fail: 0x%02x\n", r);
        return r;
    }
    m_log_t(M_NRF2401_H, "nrf irq init success\n");
    return 0;
}

static int m_nrf_reg_init()
{
    
    m_nrf_reg_write(M_NRF_REG_EN_AA, M_NRF_REG_EN_AA_VAL);
    m_nrf_reg_write(M_NRF_REG_EN_RXADDR, M_NRF_REG_EN_RXADDR_VAL);
    m_nrf_reg_write(M_NRF_REG_SETUP_AW, M_NRF_REG_SETUP_AW_VAL);
    m_nrf_reg_write(M_NRF_REG_SETUP_RETR, M_NRF_REG_SETUP_RETR_VAL);
    m_nrf_reg_write(M_NRF_REG_RF_CH, M_NRF_REG_RF_CH_VAL);
    m_nrf_reg_write(M_NRF_REG_RF_SETUP, M_NRF_REG_RF_SETUP_VAL);

    unsigned char *addr = m_nrf_reg_rx_addr_val;
    unsigned int width = sizeof(m_nrf_reg_rx_addr_val)/sizeof(unsigned char);
    for (int i = 0; i < 6; i++) {
        if (i < 2) {
            m_nrf_reg_write_buf(M_NRF_REG_RX_ADDR_P0 + i, addr, width); // 接收数据通道(0~1)地址
        } else {
            m_nrf_reg_write(M_NRF_REG_RX_ADDR_P0 + i, *(addr + (width - 1))); // 接收数据通道(2~5)地址
        }                               
        *(addr + (width - 1)) = (unsigned char)((unsigned int)(*(addr + (width - 1))) + 1); //（即每通道地址较前一条通道地址加1）
        m_nrf_reg_write(M_NRF_REG_RX_PW_P0 + i, M_NRF_REG_RX_PW_VAL);                       // 接收数据通道(0 + i)有效数据宽度
    }
    m_nrf_reg_write_buf(M_NRF_REG_RX_ADDR_P0, m_nrf_reg_tx_addr_val, width);                // 发送增强型
    m_nrf_reg_write_buf(M_NRF_REG_TX_ADDR, m_nrf_reg_tx_addr_val, width);                   // 发送地址

    m_log_t(M_NRF2401_H, "nrf reg init finish\n");
    
    #ifdef M_LOG_TRACE
    if (strstr(M_LOG_TRACE, M_NRF2401_H) != 0 || strstr(M_LOG_TRACE, M_LOG_ALL) != 0) {
        m_nrf_reg_value();
    }
    #endif
    return 0;
}

static int m_nrf_reg_value()
{
    unsigned char val;
    m_nrf_reg_read(M_NRF_REG_CONFIG, &val);
    m_nrf_reg_read(M_NRF_REG_EN_AA, &val);
    m_nrf_reg_read(M_NRF_REG_EN_RXADDR, &val);
    m_nrf_reg_read(M_NRF_REG_SETUP_AW, &val);
    m_nrf_reg_read(M_NRF_REG_SETUP_RETR, &val);
    m_nrf_reg_read(M_NRF_REG_RF_CH, &val);
    m_nrf_reg_read(M_NRF_REG_RF_SETUP, &val);

    unsigned char *buf = m_nrf_reg_rx_addr_val;
    unsigned int width = sizeof(m_nrf_reg_rx_addr_val)/sizeof(unsigned char);
    for (int i = 0; i < 6; i++) {
        if (i < 2) {
            m_nrf_reg_read_buf(M_NRF_REG_RX_ADDR_P0 + i, buf, width);       // 接收数据通道(0~1)地址
        } else {
            m_nrf_reg_read(M_NRF_REG_RX_ADDR_P0 + i, &val);                 // 接收数据通道(2~5)地址
        }
        m_nrf_reg_read(M_NRF_REG_RX_PW_P0 + i, &val);                       // 接收数据通道(0 + i)有效数据宽度
    }
    m_nrf_reg_read_buf(M_NRF_REG_TX_ADDR, buf, width);                      // 发送地址

    m_log_t(M_NRF2401_H, "nrf reg read finish\n");
    return 0;
}

static int m_nrf_reg_write(unsigned int reg, unsigned char val)
{
    unsigned int size_ = 2;
    unsigned char buf_[size_];
    buf_[0] = (unsigned char)(M_NRF_REG_WRITE + reg);
    buf_[1] = val;
    #ifdef M_LOG_DEBUG
    unsigned char hex[size_ * 2 + 1];
    m_to_hex(buf_, size_, hex);
    m_log_d(M_NRF2401_H, "reg_write-> reg=0x%02x, val=0x%02x, cmd=%s\n", (unsigned char)reg, (unsigned char)val, hex);
    #endif
    m_spi_data data = {
        .sendBuf = buf_,
        .recvBuf = buf_,
        .recvSize = size_
    };
    int r = m_spi_host_write_read(&data);
    m_delay(200);
    if (r != 0) {
        m_log_e(M_NRF2401_H, "nrf reg write fail: reg=0x%02x, val=0x%02x, err=0x%02x\n", (unsigned char)reg, val, r);
        return r;
    }
    return 0;
}

static int m_nrf_reg_write_buf(unsigned int reg, unsigned char *buf, unsigned int size)
{
    unsigned int size_ = 1 + size;
    unsigned char buf_[size_];
    buf_[0] = (unsigned char)(M_NRF_REG_WRITE + reg);
    for (unsigned int i = 0; i < size; i++) {
        *(buf_ + 1 + i) = *(buf + i);
    }
    #ifdef M_LOG_DEBUG
    unsigned char hex[size_ * 2 + 1];
    m_to_hex(buf_, size_, hex);
    m_log_d(M_NRF2401_H, "reg_write_buf-> reg=0x%02x, size=%d, cmd=%s\n", (unsigned char)reg, size, hex);
    #endif
    m_spi_data data = {
        .sendBuf = buf_,
        .recvBuf = buf_,
        .recvSize = size_
    };
    int r = m_spi_host_write_read(&data);
    m_delay(200);
    if (r != 0) {
        m_log_e(M_NRF2401_H, "nrf reg write buf fail: reg=0x%02x, size=%d, err=0x%02x\n", (unsigned char)reg, size, r);
        return r;
    }
    return 0;
}

static int m_nrf_reg_read(unsigned int reg, unsigned char *val)
{
    unsigned int size_ = 2;
    unsigned char buf_[size_];
    buf_[0] = (unsigned char)(M_NRF_REG_READ | (reg & 0x1F));
    m_log_d(M_NRF2401_H, "reg_read-> reg=0x%02x, cmd=%02x\n", (unsigned char)reg, buf_[0]);
    m_spi_data data = {
        .sendBuf = buf_,
        .recvBuf = buf_,
        .recvSize = size_
    };
    int r = m_spi_host_write_read(&data);
    m_delay(200);
    if (r != 0) {
        m_log_e(M_NRF2401_H, "nrf reg read fail: reg=0x%02x, err=0x%02x\n", (unsigned char)reg, r);
        return r;
    }
    *val = *(buf_ + 1);// 第一个为指令字节，第二个字节才是有效值
    #ifdef M_LOG_DEBUG
    unsigned char hex[size_ * 2 + 1];
    m_to_hex(buf_, size_, hex);
    m_log_d(M_NRF2401_H, "reg_read-> reg=0x%02x, size=%d, recvBuf=%s\n", (unsigned char)reg, size_, hex);
    #endif
    return 0;
}

static int m_nrf_reg_read_buf(unsigned int reg, unsigned char *buf, unsigned int size)
{
    unsigned int size_ = 1 + size;
    unsigned char buf_[size_];
    buf_[0] = (unsigned char)(M_NRF_REG_READ | (reg & 0x1F));
    m_log_d(M_NRF2401_H, "reg_read_buf-> reg=0x%02x, size=%d, cmd=%02x\n", (unsigned char)reg, size, buf_[0]);
    m_spi_data data = {
        .sendBuf = buf_,
        .recvBuf = buf_,
        .recvSize = size_
    };
    int r = m_spi_host_write_read(&data);
    m_delay(200);
    if (r != 0) {
        m_log_e(M_NRF2401_H, "nrf reg read buf fail: reg=0x%02x, size=%d, err=0x%02x\n", (unsigned char)reg, size, r);
        return r;
    }
    // 第一个为指令字节，后续字节才是有效值
    for (unsigned int i = 0; i < size_; i++) {
        *(buf + i) = *(buf_ + 1 + i);
    }

    #ifdef M_LOG_DEBUG
    unsigned char hex[size_ * 2 + 1];
    m_to_hex(buf_, size_, hex);
    m_log_d(M_NRF2401_H, "reg_read_buf-> reg=0x%02x, size=%d, recvBuf=%s\n", (unsigned char)reg, size_, hex);
    #endif

    return 0;
}